package com.course.web.biz;

import com.course.domain.model.CourseInfo;
import com.course.domain.model.CoursePlan;
import com.course.domain.model.SpecInfo;
import com.course.domain.model.SpecWeek;
import com.course.domain.service.CourseService;
import com.course.domain.service.SpecService;
import com.course.util.DateUtils;
import com.course.web.model.CourseInfoVM;
import com.course.web.model.CourseItemVM;
import com.course.web.model.CourseWeekVM;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Created by Justin on 2017/6/10.
 */
@Component
public class WebCourseBiz {

    private final CourseService courseService;
    private final SpecService specService;

    @Autowired
    public WebCourseBiz(CourseService courseService, SpecService specService) {
        this.courseService = courseService;
        this.specService = specService;
    }

    public CourseInfoVM createInfo(CourseInfoVM vm) {
        vm.setSpecId(vm.getSpecId());
        CourseInfo info = courseService.createInfo(toInfo(vm));
        vm.setId(info.getId());
        return vm;
    }

    public CourseInfoVM updateInfo(CourseInfoVM vm) {
        courseService.updateInfo(toInfo(vm));
        return vm;
    }

    public CourseInfoVM deleteInfo(CourseInfoVM vm) {
        courseService.deleteInfo(toInfo(vm));
        return vm;
    }

    public CourseItemVM createItem(CourseItemVM vm) {
        CoursePlan coursePlan = courseService.createPlan(toPlan(vm));
        vm.setId(coursePlan.getId());
        return vm;
    }

    public CourseItemVM updateItem(CourseItemVM vm) {
        courseService.updatePlan(toPlan(vm));
        return vm;
    }

    public CourseInfoVM loadInfo(int courseId) {
        CourseInfo courseInfo = courseService.loadInfo(courseId);
        return transform(courseInfo);
    }

    public List<CourseInfoVM> listInfo() {
        return Lists.transform(courseService.listInfo(), this::transform);
    }

    public List<CourseWeekVM> listWeek(int courseId, int weekIdx) {
        CourseInfo courseInfo = courseService.loadInfo(courseId);
        List<CoursePlan> coursePlans = courseService.findPlan(courseId, weekIdx);
        SpecInfo specInfo = specService.loadInfo(courseInfo.getSpecId());
        List<SpecWeek> specWeeks = specService.findWeek(courseInfo.getSpecId());
        List<CourseWeekVM> vms = Lists.newArrayListWithCapacity(specInfo.getParts());
        for (int i = 0; i < specWeeks.size(); i++) {
            int partIdx = i + 1;
            vms.add(newWeek(courseId, weekIdx, partIdx));
        }
        for (CoursePlan coursePlan : coursePlans) {
            int partIdx = coursePlan.getPartIdx();
            addItem(vms.get(partIdx - 1), transform(coursePlan));
        }
        for (SpecWeek specWeek : specWeeks) {
            int partIdx = specWeek.getPartIdx();
            fixItem(vms.get(partIdx - 1), specWeek);
        }
        return vms;
    }

    private CourseInfoVM transform(CourseInfo courseInfo) {
        CourseInfoVM vm = new CourseInfoVM();
        vm.setId(courseInfo.getId());
        vm.setSpecId(courseInfo.getSpecId());
        vm.setWeeks(courseInfo.getWeeks());
        vm.setTitle(courseInfo.getTitle());
        vm.setDetail(courseInfo.getDetail());
        vm.setDate(DateUtils.toLocalDate(courseInfo.getBeginDate()));
        return vm;
    }

    private CourseItemVM transform(CoursePlan coursePlan) {
        int courseId = coursePlan.getCourseId();
        int weekIdx = coursePlan.getWeekIdx();
        int weekDay = coursePlan.getWeekDay();
        int partIdx = coursePlan.getPartIdx();
        CourseItemVM vm = new CourseItemVM(courseId, weekIdx, weekDay, partIdx);
        vm.setId(coursePlan.getId());
        vm.setTaskId(coursePlan.getTaskId());
        vm.setTaskType(coursePlan.getTaskType());
        return vm;
    }

    private CourseInfo toInfo(CourseInfoVM vm) {
        CourseInfo courseInfo = new CourseInfo();
        courseInfo.setId(vm.getId());
        courseInfo.setSpecId(vm.getSpecId());
        courseInfo.setWeeks(vm.getWeeks());
        courseInfo.setTitle(vm.getTitle());
        courseInfo.setDetail(vm.getDetail());
        courseInfo.setBeginDate(DateUtils.toDate(vm.getDate()));
        courseInfo.setStatus(1);
        return courseInfo;
    }

    private CoursePlan toPlan(CourseItemVM vm) {
        CoursePlan coursePlan = new CoursePlan();
        coursePlan.setId(vm.getId());
        coursePlan.setCourseId(vm.getCourseId());
        coursePlan.setWeekIdx(vm.getWeekIdx());
        coursePlan.setWeekDay(vm.getWeekDay());
        coursePlan.setPartIdx(vm.getPartIdx());
        coursePlan.setTaskId(vm.getTaskId());
        coursePlan.setTaskType(vm.getTaskType());
        coursePlan.setStatus(1);
        return coursePlan;
    }

    private CourseWeekVM newWeek(int courseId, int weekIdx, int partIdx) {
        CourseWeekVM vm = new CourseWeekVM(courseId, weekIdx, partIdx);
        vm.setWorkday("");
        vm.setWeekend("");
        vm.setItems(new CourseItemVM[8]);
        return vm;
    }

    private void addItem(CourseWeekVM week, CourseItemVM item) {
        CourseItemVM[] items = week.getItems();
        items[item.getWeekDay()] = item;
    }

    private void fixItem(CourseWeekVM vm, SpecWeek week) {
        int courseId = vm.getCourseId();
        int weekIdx = vm.getWeekIdx();
        int partIdx = vm.getPartIdx();
        vm.setWorkday(week.getWorkdayTitle());
        vm.setWeekend(week.getWeekendTitle());
        for (int weekDay = 1; weekDay <= 7; weekDay++) {
            CourseItemVM item = vm.getItem(weekDay);
            if (item == null) {
                item = new CourseItemVM(courseId, weekIdx, weekDay, partIdx);
                item.setTaskId(0);
                item.setTaskType(week.getByWeekDay(weekDay));
                vm.setItem(weekDay, item);
            }
        }
    }
}
